/**
 * 
 */
package com.xianshijian.oauth.server.controller;


import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.xianshijian.oauth.common.entity.OAuth;
import com.xianshijian.oauth.common.utils.CookieUtils;
import com.xianshijian.oauth.common.utils.JsonUtils;
import com.xianshijian.oauth.server.cache.CacheKey;
import com.xianshijian.oauth.server.service.OAuthService;
import com.xianshijian.oauth.server.service.ThirdPartyService;

/**
 * 授权确认接口:用户点击授权后由前端调用，返回code给第三方
 * 1.生成授权码并加入数据库中
 * 2.带参数重定向到redirectURL
 * 
 * @author ptzhuf
 *
 */
@Controller
public class ConfirmAuthController {
	
	@Autowired
    private OAuthService oAuthService;
	@Autowired
    private ThirdPartyService thirdPartyService;

	private static final Logger LOG = LoggerFactory.getLogger(ConfirmAuthController.class);

	@RequestMapping(value = "/oauth2/confirmAuth", method = RequestMethod.GET)
	public String confirmAuth(HttpServletRequest request, RedirectAttributes attr) throws URISyntaxException {
		try {
			//*********************************获取参数*********************************//
			String clientStamp = request.getParameter(OAuth.OAUTH_STAMP);	
			String sjkSessionId = CookieUtils.getCookieValue(request, OAuth.OAUTH_SESSION_ID);
			//授权接口传递过来的参数
			String redisKey = CacheKey.createSessionIdTempKey(sjkSessionId);
			Map<String,String> map = thirdPartyService.getCacheKey(redisKey);			
			String thirdPartyId = (String) map.get(OAuth.OAUTH_THIRD_PARTY_ID);
			String redirectURL = (String) map.get(OAuth.OAUTH_REDIRECT_URL);
			String state = (String) map.get(OAuth.OAUTH_STATE);
			String scope = (String) map.get(OAuth.OAUTH_SCOPE);
			String stamp = (String) map.get(OAuth.OAUTH_STAMP);
			
			//验证用户是否登录
			HashMap<String,String> loginMap = JsonUtils.jsonToPojo(oAuthService.checkUserLogin(sjkSessionId), HashMap.class);
					
			String isLogin = loginMap.get("isLogin");
			if (!isLogin.equals("1")) {
				attr.addAttribute("state", null);   
            	attr.addAttribute("code", null); 
				attr.addAttribute("status", OAuth.StatusCode.CLIENT_OPR_ERROR);
				attr.addAttribute("msg", "失败原因：客户端非法操作");
				return "redirect:" + redirectURL;
			}
	
			//比对stamp戳，防止第三方直接调用确认授权接口
			if(StringUtils.isBlank(clientStamp) || StringUtils.isBlank(stamp) || !clientStamp.equals(stamp)){
				attr.addAttribute("state", state);   
            	attr.addAttribute("code", null); 
				attr.addAttribute("status", OAuth.StatusCode.CLIENT_OPR_ERROR);
				attr.addAttribute("msg", "失败原因：客户端非法操作");
				return "redirect:" + redirectURL;
			}
			thirdPartyService.clearStampCacheKey(CacheKey.createSessionIdTempKey(sjkSessionId),map);
            
            //生成授权码
            String authorizationCode = UUID.randomUUID().toString();
            boolean flag = oAuthService.addAuthCode(thirdPartyId,authorizationCode,sjkSessionId);
            //封装返回参数     
            if(flag==true){
            	attr.addAttribute("state", state);   
            	attr.addAttribute("code", authorizationCode); 
            	attr.addAttribute("status", OAuth.StatusCode.OK);
				attr.addAttribute("msg", "返回成功");
            }else{
            	attr.addAttribute("state", state); 
            	attr.addAttribute("code", null); 
            	attr.addAttribute("status", OAuth.StatusCode.SERVER_ERROR);
				attr.addAttribute("msg", "失败原因：服务端错误");
            }
            //重定向
            return "redirect:" + redirectURL;
            
		} catch (Exception e) {
			//打印错误日志
			String msg = "调用auth出错 : {" + e.getMessage() + "}";
			String errMsg = new StringBuilder(msg).append(", 请求参数为:[{}]").toString();
			LOG.error(errMsg, Arrays.asList(new Object[] { request }));
			LOG.error("错误信息:", e);
			throw new RuntimeException(msg, e);
		}
	}
}
